package com.sky.service.user.impl;


import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.exception.*;
import com.sky.mapper.user.*;
import com.sky.pojo.*;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.common.OrderDispatchService;
import com.sky.service.user.OrderService;
import com.sky.utils.MapUtils;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Future;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private AddressBookServiceMapper addressBookServiceMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private WeChatPayUtil weChatPayUtil;

//    @Autowired
//    private SignUtils;
    /**
     * 用户下单
     *
     * @param ordersSubmitDTO
     * @return
     */
    @Override
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        //获取用户id
        Long userId = BaseContext.getCurrentId();
        //查找默认地址
        Integer isDefault = StatusConstant.ENABLE;
        //1.处理业务异常（地址为空、订单为空）
        //根据用户id获取用户的地址，判断用户的地址是否为空
        AddressBook addressBook = addressBookServiceMapper.queryAddressBookUserId(userId, isDefault);
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //判断用户的购物车是否为空
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.list(userId);
        if (shoppingCarts.isEmpty()) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //向订单表插入数据
        Orders orders = new Orders();
        //将前端传过来的数据映射的orders中
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        //插入ordersSubmitDTO没有的数据
        // 获取当前的下单时间
        orders.setOrderTime(LocalDateTime.now());
        //将当前的时间戳作为当前用户的订单号
        orders.setNumber(UUID.randomUUID().toString().replaceAll("-", ""));
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setUserId(userId);
        orders.setAddressBookId(addressBook.getId());
        orders.setPayMethod(Orders.UN_PAID);
        orders.setPhone(addressBook.getPhone());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setDeliveryStatus(Orders.UN_PAID);
        //sql语句要返回order的id
        orderMapper.insertData(orders);
        //创建一个集合
        List<OrderDetail> orderDetailList = new ArrayList<>();
        //向订单详细表插入n条数据
        for (ShoppingCart sc : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            //将购物车的数据映射到orderDetail
            BeanUtils.copyProperties(sc, orderDetail);
            //设置order_id
            orderDetail.setOrderId(orders.getId());
            orderDetailList.add(orderDetail);
        }
        orderDetailMapper.AddData(orderDetailList);
        //清空当前用户的购物车数据
        shoppingCartMapper.cleanShoppingCart(userId);
        //返回封装数据
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderAmount(orders.getAmount());
        orderSubmitVO.setOrderTime(orders.getOrderTime());
        return orderSubmitVO;
    }
    /**
     * 小程序支付
     */
    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO dto) {
        //获取用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.selectById(userId);
        //调用微信支付接口，生成预支付交易单
        JSONObject jsonObject = weChatPayUtil.pay(
                dto.getOrderNumber(),//商户订单
                new BigDecimal("0.01"),//支付金额
                "苍穹外卖",//商品描述
                user.getOpenid());//微信用户的openid
        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }
        OrderPaymentVO orderPaymentVO = jsonObject.toJavaObject(OrderPaymentVO.class);
        orderPaymentVO.setPackageStr(jsonObject.getString("package"));
        return orderPaymentVO;
    }
    /**
     * 获取用户送餐期望时间
     */
    @Override
    public String getEstimatedDeliveryTime(Long shopId, String customerAddress) {
        // 预计送达时间 = 当前时间 +  菜品制作时间 + 配送时间 + 预留时间（10分钟）
        //1.菜品的制作时间  分钟
        Integer totalMakeTime = shoppingCartMapper.selectTotalMakeTimeByUserId(BaseContext.getCurrentId());
        //2.配送时间
        Merchant merchant = merchantMapper.selectById(shopId);
        //秒
        int costTime = MapUtils.baoiduTwoPointCostTime(merchant.getShopAddress(), customerAddress);
        LocalDateTime dateTime = LocalDateTime.now().plusSeconds(totalMakeTime * 60 + costTime + 600);
        return dateTime.toString();
    }
    /**
     * 历史订单查询
     */
    @Override
    public PageResult pageQueryUser(OrdersPageQueryDTO ordersPageQueryDTO) {
        //设置分页
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        //获取userId并存入ordersPageQueryDTO对象中
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        //将status存入ordersPageQueryDTO对象中
        ordersPageQueryDTO.setStatus(ordersPageQueryDTO.getPayStatus());
        //查询数据并存入Page<OrderVO> 中
        Page<OrderVO> p = orderMapper.pageQuery(ordersPageQueryDTO);
        //创建List<OrderVO>对象中
        List<OrderVO> list = new ArrayList<>();
        //判断查到的数量是否为空
        if (p != null && p.getTotal() > 0) {
            for (Orders orders : p) {
                Long orderId = orders.getId();
                //查询订单明细
                List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orderId);
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(orders, orderVO);
                orderVO.setOrderDetailList(orderDetailList);
                list.add(orderVO);
            }
        }
        return new PageResult(p.getTotal(), list);
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        //设置分页
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<Orders> pageResults = orderMapper.conditionSearch(ordersPageQueryDTO);
        return new PageResult(pageResults.getTotal(), pageResults.getResult());
    }

    @Override
    public OrderStatisticsVO statistics() {
        // 根据状态，   2 用户付款成功，等待商家接单  3.商家接单，等待骑手接单
        //     4 骑手接单成功-待取货  5待送达  6已完成  7已取消
        Integer waiting4MerchantReceiveOrders = orderMapper.countStatus(Orders.TO_BE_CONFIRMED);
        Integer waitng4RiderReceiveOrders = orderMapper.countStatus(Orders.CONFIRMED);
        Integer toBeDeliveryOnProgressOrders = orderMapper.countStatus(Orders.TOBEDELIVERED);
        Integer toBeArrivedOrders = orderMapper.countStatus(Orders.TOBEDELIVERED);
        Integer completedOrders = orderMapper.countStatus(Orders.COMPLETE_ORDER);
        Integer canceledOrders = orderMapper.countStatus(Orders.CANCELLED_ORDER);

        // 将查询出的数据封装到orderStatisticsVO中响应
        OrderStatisticsVO orderStatisticsVO = OrderStatisticsVO.builder()
                .waiting4MerchantReceiveOrders(waiting4MerchantReceiveOrders)//  status = 2  等待商家接单
                .waitng4RiderReceiveOrders(waitng4RiderReceiveOrders)//  status = 3  等待骑手接单
                .toBeDeliveryOnProgressOrders(toBeDeliveryOnProgressOrders)//  status = 4  待出货订单数
                .toBeArrivedOrders(toBeArrivedOrders)//  status = 5  待送达订单数
                .completedOrders(completedOrders) // status = 6  已完成订单数
                .canceledOrders(canceledOrders)//  status = 7  已取消订单数
                .build();
        return orderStatisticsVO;
    }

    /**
     * 订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderVO adminOrderDetails(Long id) {
        return orderMapper.adminOrderDetails(id);
    }

    /**
     * 商家取消订单
     *
     * @param ordersCancelDTO
     */
    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) {
        //修改订单数据
        Orders orders = orderMapper.getById(ordersCancelDTO.getId());
        if (orders.getStatus() == 1 || orders.getStatus() == 6 || orders.getStatus() == 7 || orders.getStatus() == 8) {
            throw new MerchantNotFoundException(MessageConstant.ORDER_STATUS_ERROR);
        }
        orders.setCancelReason(ordersCancelDTO.getCancelReason());//订单取消原因
        orders.setCancelTime(LocalDateTime.now());//订单取消时间
        orders.setStatus(Orders.TO_BE_REFUND_ORDER);//已取消，已退款
        orderMapper.update(orders);
        //TODO调用微信接口退款
        //commonPayTemplate.refund(1,1,orders.getNumber(),orders.getNumber());
    }

    /**
     * 拒单
     */
    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = orderMapper.getById(ordersRejectionDTO.getId());
        if (orders.getStatus() != 2) {
            throw new MerchantNotFoundException(MessageConstant.ORDER_STATUS_ERROR);
        }

//        //支付状态
//        Integer payStatus = ordersDB.getPayStatus();
//        if (payStatus == Orders.PAID) {
//            //用户已支付，需要退款
//            String refund = weChatPayUtil.refund(
//                    ordersDB.getNumber(),
//                    ordersDB.getNumber(),
//                    new BigDecimal(0.01),
//                    new BigDecimal(0.01));
//            log.info("申请退款：{}", refund);
//        }

        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());//订单取消原因
        orders.setCancelTime(LocalDateTime.now());//订单取消时间
        orders.setStatus(Orders.CANCELLED_ORDER);//已取消，已退款
        orderMapper.update(orders);
        //TODO调用微信接口退款
        //commonPayTemplate.refund(1,1,orders.getNumber(),orders.getNumber());
    }

    /**
     * 商家接单
     */
    @Autowired
    private OrderDispatchService orderDispatchService;
    @Override
    public Courier confirm(OrdersConfirmDTO ordersConfirmDTO) {
        //判断id是否为空
        if (ordersConfirmDTO.getId() == null) {
            throw new MerchantNotFoundException(MessageConstant.ORDER_NOT_FOUND);
        }
        //判断订单是否存在
        Orders orders = orderMapper.getById(ordersConfirmDTO.getId());
        if (orders == null) {
            throw new MerchantNotFoundException(MessageConstant.ORDER_NOT_FOUND);
        }
        //3.订单调度，系统派单，查询骑手，生成运单  -- 后续待实现
        Courier courier = orderDispatchService.dispatch(ordersConfirmDTO.getId(),null,null);
        if (courier == null) {
            //如果找不到骑手，定时任务继续找3次...还找不到，结束业务
            for (int i = 0; i < 3; i++) {
                System.out.println("第" + (i+1) + "次查询骑手");
                courier = orderDispatchService.dispatch(ordersConfirmDTO.getId(),null,null);
                if (courier != null) {
                    break;
                }
                try {
                    //每次查找间隔3秒
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        if (courier == null) {
            throw new NoCourierException("暂时找不到骑手，请稍后再试");
        }
        //4.修改订单状态
        orders.setStatus(Orders.CONFIRMED);
        orderMapper.update(orders);
        //5.封装结果，给出响应
        return courier;
    }


}
